<!DOCTYPE html>
            
<HTML>
<HEAD>
<meta name="booktitle" content="Developing Applications With Objective Caml" >
 <meta charset="ISO-8859-1"><meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0">
<META name="GENERATOR" content="hevea 1.05-7 of 2000-02-24">
<META NAME="Author" CONTENT="Christian.Queinnec@lip6.fr">
<LINK rel=stylesheet type="text/css" href="videoc-ocda.css">
<script language="JavaScript" src="videoc.js"><!--
//--></script>
<TITLE>
 Standard Library
</TITLE>
</HEAD>
<BODY class="regularBody">
<A HREF="book-ora075.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora077.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
<HR>

<H2> Standard Library</H2>
<A NAME="@concepts150"></A>
The standard library contains a group of stable modules. These are
operating system independent. There are currently 29 modules in the
standard library containing 400 functions, 30 types of which half are
abstract, 8 exceptions, 10 sub-modules, and 3 parameterized modules.
Clearly we will not describe all of the declarations in all of these
modules. Indeed, the reference manual [<A HREF="book-ora214.html#OCAML-ref"><CITE>LRVD99</CITE></A>] already does
that quite well. Only those modules presenting a new concept or a 
real difficulty in use will be detailed.<BR>
<BR>
<P>The standard library can be divided into four distinct parts: 
<UL>
<LI>
<B>linear data structures</B> (15 modules), some of which have already
appeared in the first part;

<LI><B>input-output</B> (4 modules), for the formatting of output, 
the persistence and creation of cryptographic keys;

<LI><B>parsing and lexical analysis</B> (4 modules). They are described in
chapter <A HREF="index.html#chap-AlexS">11</A> (page
<A HREF="index.html#chap-AlexS">??</A>); 

<LI><B>system interface</B> that permit communication and examination of
parameters passed to a command, directory navigation and file access.
</UL>To these four groups we add a fifth containing some utilities
for handling or creating structures such as
functions for text processing or generating pseudo-random numbers, etc. <BR>
<BR>
<A NAME="toc103"></A>
<H3> Utilities</H3>
The modules that we have named "utilities" concern:
<UL>
<LI>
 characters: the <TT>Char</TT> module primarily contains conversion functions;

<LI> object cloning: <TT>OO</TT> will be presented in chapter
<A HREF="index.html#chap-POO">15</A> (page <A HREF="index.html#chap-POO">??</A>), on object oriented programming

<LI> lazy evaluation: <TT>Lazy</TT> is first presented on page
<A HREF="book-ora039.html#subsec-paresse">??</A>;

<LI> random number generator: <TT>Random</TT> will be described below.
</UL>
<H4> Generation of Random Numbers</H4><A NAME="sec-mod-random"></A>
<A NAME="@fonctions202"></A>
The <TT>Random</TT> module is a pseudo-random number generator.
It establishes a random number generation function starting with a number
or a list of numbers called a seed. In order to ensure that the
function does not always return the same list of numbers, the programmer
must give it a different seed each time the generator is initialized.<BR>
<BR>
From this seed the function generates a succession of seemingly random
numbers. Nevertheless, an initialization with the same seed will create
the same list. To correctly initialize the generator, you need to find
some outside resource, like the date represented in milliseconds, or
the length of time since the start of the program.<BR>
<BR>
The functions of the module:
<UL>
<LI> 
 initialization: <TT>init</TT> of type <I>int -&gt; unit</I> and
<TT>full_init</TT> of type <I>int array -&gt; unit</I> 
initialize the generator. The second function takes an array of seeds.

<LI> generate random numbers: <TT>bits</TT> of type
<I>unit -&gt; int</I> returns a positive integer,
<TT>int</TT> of type <I>int -&gt; int</I> returns a positive integer
ranging from 0 to a limit given as a parameter,
and <TT>float</TT> returns a float between 0. and a limit given as a parameter.
</UL><A NAME="toc104"></A>
<H3> Linear Data Structures</H3>
<A NAME="sec-mod-string"></A>
<A NAME="sec-mod-list"></A>
<A NAME="sec-mod-array"></A>
The modules for linear data structures are:
<UL>
<LI>
 simple modules: <TT>Array</TT>, <TT>String</TT>,
<TT>List</TT>, <TT>Sort</TT>, <TT>Stack</TT>, <TT>Queue</TT>,
<TT>Buffer</TT>, <TT>Hashtbl</TT> (that is also parameterized) and
<TT>Weak</TT>; 

<LI> parameterized modules: <TT>Hashtbl</TT> (of <TT>HashedType</TT>
parameters), <TT>Map</TT> and <TT>Set</TT> (of <TT>OrderedType</TT>
parameters). 
</UL>
The parameterized modules are built from the other modules, thus
making them more generic. The construction of parameterized modules
will be presented in chapter <A HREF="index.html#chap-PM">14</A>, page
<A HREF="book-ora132.html#foncteur">??</A>. <BR>
<BR>

<H4> Simple Linear Data Structures</H4>
<A NAME="@fonctions203"></A>
<A NAME="@fonctions204"></A>
<A NAME="@fonctions205"></A>
<A NAME="@fonctions206"></A>
<A NAME="@fonctions207"></A>
<A NAME="@fonctions208"></A>
<A NAME="@fonctions209"></A>
<A NAME="@fonctions210"></A>
<A NAME="@fonctions211"></A>
The name of the module describes the type of data structures manipulated
by the module. If the type is abstract, that is to say, if the representation
is hidden, the current convention is to name it <I>t</I> inside the module.
These modules establish the following structures:
<UL>
<LI>
 module <TT>Array</TT>: vectors;

<LI> module <TT>List</TT>: lists;

<LI> module <TT>String</TT>: character strings;

<LI> module <TT>Hashtbl</TT>: hash tables (abstract type);

<LI> module <TT>Buffer</TT>: extensible character strings (abstract type);

<LI> module <TT>Stack</TT>: stacks (abstract type);

<LI> module <TT>Queue</TT>: queues or FIFO (abstract type);

<LI> module <TT>Weak</TT>: vector of weak pointers (abstract type).
</UL>Let us mention one last module that implements linear data structures:
<UL>
<LI>
 module <TT>Sort</TT>: sorting on lists and vectors, merging of lists.
</UL>
<H5> Family of common functions</H5>
Each of these modules (with the exception of <TT>Sort</TT>), has functions
for defining structures, creating/accessing elements (such as handler
functions), and converting to other types. Only the <TT>List</TT> module is 
not physically modifiable.
We will not give a complete description of all these functions.
Instead, we will focus on families of functions that one finds 
in these modules. Then we will detail the <TT>List</TT> and
<TT>Array</TT> modules that are the most commonly used structures in
functional and imperative programming.<BR>
<BR>
One finds more or less the following functionality in all these modules:
<UL>
<LI>
 a <TT>length</TT> function that takes the value of a type and
calculates an integer corresponding to its length; 

<LI> a <TT>clear</TT> function that empties the linear structure, if
it is modifiable;

<LI> a function to add an element, <TT>add</TT> in general, but
sometimes named differently according to common practice, (for example,
<TT>push</TT> for stacks); 

<LI> a function to access the n-th element, often called 
<TT>get</TT>;

<LI> a function to remove an element (often the first) 
<TT>remove</TT> or <TT>take</TT>. 
</UL>In the same way, in several modules the names of functions for traversal and
processing are the same:
<UL>
<LI>
 <TT>map</TT>: applies a function on all the elements
of the structure and returns a new structure containing the results
of these calls; 

<LI> <TT>iter</TT>: like <TT>map</TT>, but drops successive results,
and returns <EM>()</EM>.
</UL>For the structures with indexed elements we have: 
<UL>
<LI>
 <TT>fill</TT>: replaces (modifies in place) a part of the
structure with a value; 

<LI> <TT>blit</TT>: copies a part of one structure into another
structure of the same type;

<LI> <TT>sub</TT>: copies a part of one structure into a
newly created structure.
</UL> 
<H4> Modules <TT>List</TT> and <TT>Array</TT></H4>
<A NAME="@fonctions212"></A>
<A NAME="@fonctions213"></A>
We describe the functions of the two libraries while placing an emphasis
on the similarities and the particularities of each one.
For the functions common to both modules, <I>t</I>
designates either the <I>'a list</I> or <I>'a array</I> type. When a
function belongs to one module, we will use the dot notation.<BR>
<BR>

<H5> Common or analogous functionality</H5> 
<A NAME="@fonctions214"></A><A NAME="@fonctions215"></A>The first of them is the calculation of length.
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.length</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a t -&gt; int</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions216"></A><A NAME="@fonctions217"></A><A NAME="@fonctions218"></A><A NAME="@fonctions219"></A>Two functions permitting the concatenation of two structures or all the
structures of a list.
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.append</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a t -&gt; 'a t -&gt; 'a t</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.concat</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a t list -&gt; 'a t</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions220"></A><A NAME="@fonctions221"></A>Both modules have a function to access an element designated by its
position in the structure.
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.nth</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; int -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.get</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; int -&gt; 'a</I></TD>
</TR></TABLE>
</DIV>
The function to access an element at index <TT>i</TT> of a 
vector <TT>t</TT>, which is frequently used, has a syntactic shorthand:
<EM>t.(i)</EM>.<BR>
<BR>
<A NAME="@fonctions222"></A><A NAME="@fonctions223"></A><A NAME="@fonctions224"></A><A NAME="@fonctions225"></A>Two functions allow you to apply an operation to all the elements
of a structure.
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>iter</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; unit) -&gt; 'a t -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>map</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; 'b) -&gt; 'a t -&gt; 'b t</I></TD>
</TR></TABLE>
</DIV><BR>
You can use <TT>iter</TT> to print the contents of a list or a vector.


<PRE><BR># <B>let</B><CODE> </CODE>print_content<CODE> </CODE>iter<CODE> </CODE>print_item<CODE> </CODE>xs<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>iter<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>print_string<CODE>"("</CODE>;<CODE> </CODE>print_item<CODE> </CODE>x;<CODE> </CODE>print_string<CODE>")"</CODE><TT>)</TT><CODE> </CODE>xs;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>print_newline()<CODE> </CODE>;;<BR><CODE>val print_content : (('a -&gt; unit) -&gt; 'b -&gt; 'c) -&gt; ('a -&gt; 'd) -&gt; 'b -&gt; unit =</CODE><BR><CODE>  &lt;fun&gt;</CODE><BR># print_content<CODE> </CODE>List.iter<CODE> </CODE>print_int<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE>;<CODE>5</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>(1)(2)(3)(4)(5)</CODE><BR><CODE>- : unit = ()</CODE><BR># print_content<CODE> </CODE>Array.iter<CODE> </CODE>print_int<CODE> </CODE><CODE>[|</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE>;<CODE>5</CODE><CODE>|]</CODE><CODE> </CODE>;;<BR><CODE>(1)(2)(3)(4)(5)</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
The <TT>map</TT> function builds a new structure containing the
result of the application. For example, with vectors whose
contents are modifiable:


<PRE><BR># <B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[|</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>|]</CODE><CODE> </CODE>;;<BR><CODE>val a : int array = [|1; 2; 3; 4|]</CODE><BR># <B>let</B><CODE> </CODE>b<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.map<CODE> </CODE>succ<CODE> </CODE>a<CODE> </CODE>;;<BR><CODE>val b : int array = [|2; 3; 4; 5|]</CODE><BR># a<CODE>,</CODE><CODE> </CODE>b;;<BR><CODE>- : int array * int array = [|1; 2; 3; 4|], [|2; 3; 4; 5|]</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="@fonctions226"></A><A NAME="@fonctions227"></A><A NAME="@fonctions228"></A><A NAME="@fonctions229"></A>Two iterators can be used to compose successive applications of a function
on all elements of a structure.
<A NAME="fn-fold"></A> 
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>fold_left</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; 'b -&gt; 'a) -&gt; 'a -&gt; 'b t -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>fold_right</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; 'b -&gt; 'b) -&gt; 'a t -&gt; 'b -&gt; 'b</I></TD>
</TR></TABLE>
</DIV>
You have to give these iterators a base case that supplies a default value
when the structure is empty.<BR>
<BR>
<DIV ALIGN=center>
<TABLE CELLSPACING=2 CELLPADDING=0>
<TR><TD  ALIGN=left NOWRAP>fold_left<CODE> </CODE>f<CODE> </CODE>r<CODE> </CODE><CODE>[</CODE>v1;<CODE> </CODE>v2;<CODE> </CODE><CODE>...</CODE>;<CODE> </CODE><CODE> </CODE>vn<CODE>]</CODE></TD>
<TD  ALIGN=left NOWRAP>=</TD>
<TD  ALIGN=left NOWRAP>f<CODE> </CODE><CODE>...</CODE><CODE> </CODE><TT>(</TT><CODE> </CODE>f<CODE> </CODE><CODE> </CODE><TT>(</TT>f<CODE> </CODE>r<CODE> </CODE>v1<TT>)</TT><CODE> </CODE>v2<CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>...</CODE><CODE> </CODE>vn</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>fold_right<CODE> </CODE>f<CODE> </CODE><CODE>[</CODE>v1;<CODE> </CODE>v2;<CODE> </CODE><CODE>...</CODE>;<CODE> </CODE>vn<CODE>]</CODE><CODE> </CODE>r<CODE> </CODE></TD>
<TD  ALIGN=left NOWRAP>=</TD>
<TD  ALIGN=left NOWRAP>f<CODE> </CODE>v1<CODE> </CODE><TT>(</TT><CODE> </CODE>f<CODE> </CODE>v2<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>...</CODE><CODE> </CODE><TT>(</TT>f<CODE> </CODE>vn<CODE> </CODE>r<TT>)</TT><CODE> </CODE><CODE>...</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE></TD>
</TR></TABLE>
</DIV><BR>
These functions allow you to easily transform binary operations into
n-ary operations. When the operation is commutative and associative,
left and right iteration are indistinguishable:


<PRE><BR># List.fold_left<CODE> </CODE><TT>(</TT><CODE>+</CODE><TT>)</TT><CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int = 10</CODE><BR># List.fold_right<CODE> </CODE><TT>(</TT><CODE>+</CODE><TT>)</TT><CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>]</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE>;;<BR><CODE>- : int = 10</CODE><BR># List.fold_left<CODE> </CODE>List.append<CODE> </CODE><CODE>[</CODE><CODE>0</CODE><CODE>]</CODE><CODE> </CODE><CODE>[[</CODE><CODE>1</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>2</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>3</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>4</CODE><CODE>]]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [0; 1; 2; 3; 4]</CODE><BR># List.fold_right<CODE> </CODE>List.append<CODE> </CODE><CODE>[[</CODE><CODE>1</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>2</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>3</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>4</CODE><CODE>]]</CODE><CODE> </CODE><CODE>[</CODE><CODE>0</CODE><CODE>]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3; 4; 0]</CODE><BR>

</PRE>
<BR>
<BR>
Notice that, for binary concatenation, an empty list is a neutral element
to the left and to the right. We find thus, in this specific case, the
equivalence of the two expressions:


<PRE><BR># List.fold_left<CODE> </CODE>List.append<CODE> </CODE>[]<CODE> </CODE><CODE>[[</CODE><CODE>1</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>2</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>3</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>4</CODE><CODE>]]</CODE><CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3; 4]</CODE><BR># List.fold_right<CODE> </CODE>List.append<CODE> </CODE><CODE>[[</CODE><CODE>1</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>2</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>3</CODE><CODE>]</CODE>;<CODE>[</CODE><CODE>4</CODE><CODE>]]</CODE><CODE> </CODE>[]<CODE> </CODE>;;<BR><CODE>- : int list = [1; 2; 3; 4]</CODE><BR>

</PRE>

We have, in fact, found the <TT>List.concat</TT> function.<BR>
<BR>

<H5> Operations specific to lists.</H5>
<A NAME="@fonctions230"></A>
<A NAME="@fonctions231"></A>
<A NAME="@fonctions232"></A>
<A NAME="@fonctions233"></A>
<A NAME="@fonctions234"></A>
<A NAME="@fonctions235"></A>
<A NAME="@fonctions236"></A>
<A NAME="@fonctions237"></A>
It is useful to have the following list functions that are provided by
the <TT>List</TT> module:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.hd</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>first element of the list</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.tl</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>the list, without its first element</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.rev</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; 'a list</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>reversal of a list</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.mem</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a -&gt; 'a list -&gt; bool</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>membership test</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.flatten</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list list -&gt; 'a list</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>flattens a list of lists</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.rev_append</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; 'a list -&gt; 'a list</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>is the same as <EM>append (rev l1) l2</EM></TD>
</TR></TABLE>
</DIV>
The first two functions are partial. They are not defined on the empty
list and raise a <TT>Failure</TT> exception. There is a variant of
<TT>mem</TT>: <TT>memq</TT> that uses physical equality.


<PRE><BR># <B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val c : int * int = 1, 2</CODE><BR># <B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[</CODE>c<CODE>]</CODE><CODE> </CODE>;;<BR><CODE>val l : (int * int) list = [1, 2]</CODE><BR># List.memq<CODE> </CODE><TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE>2</CODE><TT>)</TT><CODE> </CODE>l<CODE> </CODE>;;<BR><CODE>- : bool = false</CODE><BR># List.memq<CODE> </CODE>c<CODE> </CODE>l<CODE> </CODE>;;<BR><CODE>- : bool = true</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="@fonctions238"></A><A NAME="@fonctions239"></A>The <TT>List</TT> module provides two iterators that generalize
boolean conjunction and disjunction (and / or):
<TT>List.for_all</TT> and <TT>List.exists</TT> that are defined by
iteration:


<PRE><BR># <B>let</B><CODE> </CODE>for_all<CODE> </CODE>f<CODE> </CODE>xs<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.fold_right<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>fun</B><CODE> </CODE>b<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>f<CODE> </CODE>x<TT>)</TT><CODE> </CODE><CODE>&amp;</CODE><CODE> </CODE>b<TT>)</TT><CODE> </CODE>xs<CODE> </CODE><B>true</B><CODE> </CODE>;;<BR><CODE>val for_all : ('a -&gt; bool) -&gt; 'a list -&gt; bool = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>exists<CODE> </CODE>f<CODE> </CODE>xs<CODE> </CODE><CODE>=</CODE><CODE> </CODE>List.fold_right<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE><B>fun</B><CODE> </CODE>b<CODE> </CODE>-&gt;<CODE> </CODE><TT>(</TT>f<CODE> </CODE>x<TT>)</TT><CODE> </CODE><B>or</B><CODE> </CODE>b<TT>)</TT><CODE> </CODE>xs<CODE> </CODE><B>false</B><CODE> </CODE>;;<BR><CODE>val exists : ('a -&gt; bool) -&gt; 'a list -&gt; bool = &lt;fun&gt;</CODE><BR>

</PRE>

<A NAME="@fonctions240"></A><A NAME="@fonctions241"></A><BR>
<BR>
There are variants of the iterators in the <TT>List</TT> module that take
two lists as arguments and traverse them in parallel (<TT>iter2</TT>,
<TT>map2</TT>, etc.). If they are not the same size, the
<TT>Invalid_argument</TT> exception is raised.<BR>
<BR>
<A NAME="@fonctions242"></A><A NAME="@fonctions243"></A>The elements of a list can be searched using the criteria provided by
the following boolean functions:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.find</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; bool) -&gt; 'a list -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.find_all</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; bool) -&gt; 'a list -&gt; 'a
list</I></TD>
</TR></TABLE>
</DIV>
<A NAME="@fonctions244"></A>The <TT>find_all</TT> function has an alias: <TT>filter</TT>.
<A NAME="@fonctions245"></A><BR>
<BR>
A variant of the general search function is the partitioning of a list:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.partition</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; bool) -&gt; 'a list -&gt; 'a list * 'a list</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions246"></A><A NAME="@fonctions247"></A>The <TT>List</TT> module has two often necessary utility functions permitting
the division and creation of lists of pairs:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.split</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a * 'b) list -&gt; 'a list * 'b list</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.combine</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; 'b list -&gt; ('a * 'b) list</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@concepts151"></A><A NAME="@fonctions248"></A><A NAME="@fonctions249"></A><A NAME="@fonctions250"></A>Finally, a structure combining lists and pairs is often used:
association lists. They are useful to store values associated to keys.
These are lists of pairs such that the first entry is a key and the second
is the information associated to the key. One has these data structures to
deal with pairs:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>List.assoc</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a -&gt; ('a * 'b) list -&gt; 'b</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>extract the information associated to a key</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.mem_assoc</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a -&gt; ('a * 'b) list -&gt; bool</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>test the existence of a key</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>List.remove_assoc</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a -&gt; ('a * 'b) list -&gt; ('a
* 'b) list</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>deletion of an element corresponding to a key</TD>
</TR></TABLE>
</DIV>
<A NAME="@fonctions251"></A><A NAME="@fonctions252"></A>
<A NAME="@fonctions253"></A>Each of these functions has a variant using physical equality 
instead of structural equality: <TT>List.assq</TT>,
<TT>List.mem_assq</TT> and <TT>List.remove_assq</TT>. <BR>
<BR>

<H5> Handlers specific to Vectors.</H5>
<A NAME="@fonctions254"></A> 
<A NAME="@fonctions255"></A>
The vectors that imperative programmers often use are physically modifiable
structures. The <TT>Array</TT> module furnishes a function to change the
value of an element:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.set</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; int -&gt; 'a -&gt; unit</I></TD>
</TR></TABLE>
</DIV>
Like <TT>get</TT>, the <TT>set</TT> function has a syntactic shortcut:
<EM>t.(i) &lt;- a</EM>.<BR>
<BR>
<A NAME="@fonctions256"></A><A NAME="@fonctions257"></A>There are three vector allocation functions:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.create</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int -&gt; 'a -&gt; 'a array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>creates a vector of a given size whose
 elements are all initialized with the same value</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.make</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int -&gt; 'a -&gt; 'a array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>alias for <TT>create</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.init</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int -&gt; (int -&gt; 'a) -&gt; 'a array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>creates a vector of a given size whose
 elements are each initialized with the result of the application of
a function to the element's index</TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions258"></A>
Since they are frequently used, the <TT>Array</TT> module has two functions
for the creation of matrices (vectors of vectors):
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.create_matrix</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int -&gt; int -&gt; 'a -&gt; 'a array array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.make_matrix</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int -&gt; int -&gt; 'a -&gt; 'a array
array</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions259"></A>
The <TT>set</TT> function is generalized as a function modifying the values
on an interval described by a starting index and a length:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.fill</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; int -&gt; int -&gt; 'a -&gt; unit</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions260"></A><A NAME="@fonctions261"></A>One can copy a whole vector or extract a sub-vector (described by a starting
index and a length) to obtain a new structure:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.copy</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; 'a array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.sub</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; int -&gt; int -&gt; 'a array</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="@fonctions262"></A>
The copy or extraction can also be done towards another vector:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.blit</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; int -&gt; 'a array -&gt; int -&gt; int -&gt; unit</I></TD>
</TR></TABLE>
</DIV>
The first argument is the index into the first vector, the second is
the index into the second vector and the third is the number of values copied.
The three functions
<TT>blit</TT>, <TT>sub</TT> and <TT>fill</TT> raise the
<TT>Invalid_argument</TT> exception. <BR>
<BR>
<A NAME="@fonctions263"></A><A NAME="@fonctions264"></A>
The privileged use of indices in the vector manipulation functions
leads to the definition of two specific iterators:
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.iteri</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>(int -&gt; 'a -&gt; unit) -&gt; 'a array -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.mapi</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>(int -&gt; 'a -&gt; 'b) -&gt; 'a array -&gt; 'b array</I></TD>
</TR></TABLE>
</DIV><BR>
They apply a function whose first argument is the index of the
affected element.


<PRE><BR># <CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>f<CODE> </CODE>i<CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>i<TT>)</TT><CODE> </CODE><CODE>^</CODE><CODE> </CODE><CODE>":"</CODE><CODE> </CODE><CODE>^</CODE><CODE> </CODE><TT>(</TT>string_of_int<CODE> </CODE>a<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Array.mapi<CODE> </CODE>f<CODE> </CODE><CODE> </CODE><CODE>[|</CODE><CODE> </CODE><CODE>4</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>1</CODE>;<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>|]</CODE><CODE> </CODE>;;<BR><CODE>- : string array = [|"0:4"; "1:3"; "2:2"; "3:1"; "4:0"|]</CODE><BR>

</PRE>
<BR>
<BR>
Although the <TT>Array</TT> module does not have a function to modify the
contents of all the elements in a vector, this effect can be easily obtained
using <TT>iteri</TT>:


<PRE><BR># <B>let</B><CODE> </CODE>iter_and_set<CODE> </CODE>f<CODE> </CODE>t<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE>Array.iteri<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>i<CODE> </CODE>-&gt;<CODE> </CODE><B>fun</B><CODE> </CODE>x<CODE> </CODE>-&gt;<CODE> </CODE>t<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE>f<CODE> </CODE>x<TT>)</TT><CODE> </CODE>t<CODE> </CODE>;;<BR><CODE>val iter_and_set : ('a -&gt; 'a) -&gt; 'a array -&gt; unit = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>[|</CODE><CODE>0</CODE>;<CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>|]</CODE><CODE> </CODE>;;<BR><CODE>val v : int array = [|0; 1; 2; 3; 4|]</CODE><BR># iter_and_set<CODE> </CODE>succ<CODE> </CODE>v<CODE> </CODE>;;<BR><CODE>- : unit = ()</CODE><BR># v<CODE> </CODE>;;<BR><CODE>- : int array = [|1; 2; 3; 4; 5|]</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="@fonctions265"></A><A NAME="@fonctions266"></A>Finally, the <TT>Array</TT> module provides two list conversion functions: 
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>Array.of_list</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a list -&gt; 'a array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>Array.to_list</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a array -&gt; 'a list</I></TD>
</TR></TABLE>
</DIV><BR>
<A NAME="toc105"></A>
<H3> Input-output</H3>
<A NAME="@concepts152"></A>
<A NAME="@fonctions267"></A>
<A NAME="@fonctions268"></A>
<A NAME="@fonctions269"></A>
<A NAME="@fonctions270"></A>
The standard library has four input-output modules:
<UL>
<LI>
 module <TT>Printf</TT>: for the formatting of output;

<LI> <TT>Format</TT>: pretty-printing facility to format text within
``pretty-printing boxes''. The pretty-printer breaks lines at specified
break hints, and indents lines according to the box structure.

<LI> module <TT>Marshal</TT>: implements a mechanism for persistent values;

<LI> module <TT>Digest</TT>: for creating unique keys.
</UL>
The description of the <TT>Marshal</TT> module will be given later in the
chapter when we begin to discuss persistent data structures (see page
<A HREF="book-ora076.html#sec-persist">??</A>).<BR>
<BR>

<H4> Module <TT>Printf</TT></H4>
<A NAME="subsec-printf"></A>
<A NAME="@fonctions271"></A>
The <TT>Printf</TT> module formats text using the rules of the
<TT>printf</TT> function in the C language library. The display format
is represented as a character string that will be decoded
according to the conventions of <TT>printf</TT> in C, that is to say,
by specializing the <TT>%</TT> character. This character followed by
a letter indicates the type of the argument at this position. The following
format <EM>"(x=%d, y=%d)"</EM> indicates that it should put two integers
in place of the <EM>%d</EM> in the output string.<BR>
<BR>

<H5> Specification of formats.</H5>
<A NAME="@fonctions272"></A>
A format defines the parameters for a printed string.
Those, of basic types: <I>int</I>, <I>float</I>,
<I>char</I> and <I>string</I>, will be converted to strings and will
replace their occurrence in the printed string.
The values 77 and 43 provided to the format
<EM>"(x=%d, y=%d)"</EM> will generate the complete printed string
<CODE>"(x=77, y=43)"</CODE>. The principal letters indicating the type of
conversion to carry out are given in figure <A HREF="book-ora076.html#fig-lettres">8.1</A>. <BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP>Type</TD>
<TD  ALIGN=left NOWRAP>Letter</TD>
<TD  ALIGN=left NOWRAP>Result</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>integer</TD>
<TD  ALIGN=left NOWRAP><TT>d</TT> or <TT>i</TT></TD>
<TD  ALIGN=left NOWRAP>signed decimal</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP><TT>u</TT></TD>
<TD  ALIGN=left NOWRAP>unsigned decimal</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP><TT>x</TT></TD>
<TD  ALIGN=left NOWRAP>unsigned hexadecimal, lower case form</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP><TT>X</TT></TD>
<TD  ALIGN=left NOWRAP>same, with upper case letters</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>character</TD>
<TD  ALIGN=left NOWRAP><TT>c</TT></TD>
<TD  ALIGN=left NOWRAP>character</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>string</TD>
<TD  ALIGN=left NOWRAP><TT>s</TT></TD>
<TD  ALIGN=left NOWRAP>string</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>float</TD>
<TD  ALIGN=left NOWRAP><TT>f</TT></TD>
<TD  ALIGN=left NOWRAP>decimal</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP><TT>e</TT> or <TT>E</TT></TD>
<TD  ALIGN=left NOWRAP>scientific notation</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP><TT>g</TT> or <TT>G</TT></TD>
<TD  ALIGN=left NOWRAP>same</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>boolean</TD>
<TD  ALIGN=left NOWRAP><TT>b</TT></TD>
<TD  ALIGN=left NOWRAP><TT>true</TT> or <TT>false</TT></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>special</TD>
<TD  ALIGN=left NOWRAP><TT>a</TT> or <TT>t</TT></TD>
<TD  ALIGN=left NOWRAP>functional parameter</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>of type <I>(out_channel -&gt; 'a -&gt; unit) -&gt; 'a -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>or <I>out_channel -&gt; unit</I></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.1: <A NAME="fig-lettres"></A>Conversion conventions.</DIV><BR>

<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The format also allows one to specify the justification of the conversion,
which allows for the alignment of the printed values.
One can indicate the size in conversion characters. For this one 
places between the <EM>%</EM> character and the type of conversion an
integer number as in <EM>%10d</EM> that indicates a conversion 
to be padded on the right to ten characters. If the size of the result of the
conversion exceeds this limit, the limit will be discarded. A negative number
indicates left justification. For conversions of floating point
numbers, it is helpful to be able to specify the printed precision.
One places a decimal point followed by a number to indicate 
the number of characters after the decimal point as in
<EM>%.5f</EM> that indicates five characters to the right of the decimal
point.<BR>
<BR>
There are two specific format letters: <TT>a</TT> and
<TT>t</TT> that indicate a functional argument. Typically, a print function
defined by the user. This is specific to Objective CAML.<BR>
<BR>

<H5> Functions in the module</H5> 
<A NAME="@fonctions273"></A>
<A NAME="@fonctions274"></A>
<A NAME="@fonctions275"></A>
<A NAME="@fonctions276"></A>
<A NAME="@fonctions277"></A>
The types of the five functions in this module are given in figure
<A HREF="book-ora076.html#fig-printf">8.2</A>.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV> 
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>fprintf</TT></TD>
<TD  ALIGN=left NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>out_channel -&gt; ('a, out_channel, unit) format -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>printf</TT></TD>
<TD  ALIGN=left NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I> ('a, out_channel, unit) format -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>eprintf</TT></TD>
<TD  ALIGN=left NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a, out_channel, unit) format -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>sprintf</TT></TD>
<TD  ALIGN=left NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a, unit, string) format -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>bprintf</TT></TD>
<TD  ALIGN=left NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>Buffer.t -&gt; ('a, Buffer.t, string) format -&gt; 'a</I></TD>
</TR></TABLE>
</DIV><BR>
<DIV ALIGN=center>Figure 8.2: <A NAME="fig-printf"></A><TT>Printf</TT> formatting functions.</DIV><BR>

<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The <TT>fprintf</TT> function takes a channel, a format and arguments of
types described in the format. The <TT>printf</TT> and <TT>eprintf</TT>
functions are specializations on standard output and standard error.
Finally, <TT>sprintf</TT> and <TT>bprintf</TT> do not print the result of
the conversion, but instead return the corresponding string.<BR>
<BR>
Here are some simple examples of the utilization of formats.


<PRE><BR># Printf.printf<CODE> </CODE><CODE>"(x=%d, y=%d)"</CODE><CODE> </CODE><CODE>3</CODE><CODE>4</CODE><CODE> </CODE><CODE>7</CODE><CODE>8</CODE><CODE> </CODE>;;<BR><CODE>(x=34, y=78)- : unit = ()</CODE><BR># Printf.printf<CODE> </CODE><CODE>"name = %s, age = %d"</CODE><CODE> </CODE><CODE>"Patricia"</CODE><CODE> </CODE><CODE>1</CODE><CODE>8</CODE><CODE> </CODE>;;<BR><CODE>name = Patricia, age = 18- : unit = ()</CODE><BR># <B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Printf.sprintf<CODE> </CODE><CODE>"%10.5f\n%10.5f\n"</CODE><CODE> </CODE><TT>(</TT><CODE>-.</CODE><CODE>1</CODE><CODE>2</CODE><CODE>.</CODE><CODE>2</CODE><CODE>4</CODE><TT>)</TT><CODE> </CODE><TT>(</TT><CODE>2</CODE><CODE>.</CODE><CODE>3</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>0</CODE><CODE>8</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val s : string = " -12.24000\n   2.30000\n"</CODE><BR># print_string<CODE> </CODE>s<CODE> </CODE>;;<BR><CODE>-12.24000</CODE><BR><CODE>   2.30000</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>
The following example builds a print function from a matrix of floats
using a given format.


<PRE><BR># <B>let</B><CODE> </CODE>print_mat<CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"\n"</CODE><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><TT>(</TT>Array.length<CODE> </CODE>m<TT>)</TT><CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>do</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>j<CODE>=</CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE><TT>(</TT>Array.length<CODE> </CODE>m<CODE>.</CODE><TT>(</TT><CODE>0</CODE><TT>)</TT><TT>)</TT><CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>do</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"%10.3f"</CODE><CODE> </CODE>m<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE>.</CODE><TT>(</TT>j<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"\n"</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B><CODE> </CODE>;;<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE>val print_mat : float array array -&gt; unit = &lt;fun&gt;</CODE><BR># print_mat<CODE> </CODE><TT>(</TT>Array.create<CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE> </CODE><CODE>[|</CODE><CODE> </CODE><CODE>1</CODE><CODE>.</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>-.</CODE><CODE>4</CODE><CODE>4</CODE><CODE>.</CODE><CODE>2</CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE><CODE>5</CODE><CODE>.</CODE><CODE>2</CODE><CODE> </CODE><CODE>|]</CODE><TT>)</TT><CODE> </CODE>;;<BR><BR><CODE>     1.200   -44.220    35.200</CODE><BR><CODE>     1.200   -44.220    35.200</CODE><BR><CODE>     1.200   -44.220    35.200</CODE><BR><CODE>     1.200   -44.220    35.200</CODE><BR><CODE>- : unit = ()</CODE><BR>

</PRE>
<BR>
<BR>

<H5> Note on the <I>format</I> type.</H5>
<A NAME="@fonctions278"></A>
The description of a format adopts the syntax of character strings,
but it is not a value of type <I>string</I>. The decoding of a format,
according to the preceding conventions, builds a value of type
<I>format</I> where the <I>'a</I> parameter is instantiated 
either with <I>unit</I> if the format does not mention a parameter,
or by a functional type corresponding to a function able to receive
as many arguments as are mentioned and returning a value of type
<I>unit</I>.<BR>
<BR>
One can illustrate this process by partially applying the
<TT>printf</TT> function to a format:


<PRE><BR># <B>let</B><CODE> </CODE>p3<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"begin\n%d is val1\n%s is val2\n%f is val3\n"</CODE><CODE> </CODE>;;<BR><CODE>begin</CODE><BR><CODE>val p3 : int -&gt; string -&gt; float -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

One obtains thus a function that takes three arguments. Note that the
word <TT>begin</TT> had already been printed. Another format would have given
another type of function:


<PRE><BR># <B>let</B><CODE> </CODE>p2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"begin\n%f is val1\n%s is val2\n"</CODE>;;<BR><CODE>begin</CODE><BR><CODE>val p2 : float -&gt; string -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>

In providing arguments one by one to <TT>p3</TT>, one
progressively obtains the output.


<PRE><BR># <B>let</B><CODE> </CODE>p31<CODE> </CODE><CODE>=</CODE><CODE> </CODE>p3<CODE> </CODE><CODE>4</CODE><CODE>5</CODE><CODE> </CODE>;;<BR><CODE>45 is val1</CODE><BR><CODE>val p31 : string -&gt; float -&gt; unit = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>p32<CODE> </CODE><CODE>=</CODE><CODE> </CODE>p31<CODE> </CODE><CODE>"hello"</CODE><CODE> </CODE>;;<BR><CODE>hello is val2</CODE><BR><CODE>val p32 : float -&gt; unit = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>p33<CODE> </CODE><CODE>=</CODE><CODE> </CODE>p32<CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>1</CODE><CODE>4</CODE><CODE> </CODE>;;<BR><CODE>3.140000 is val3</CODE><BR><CODE>val p33 : unit = ()</CODE><BR># p33<CODE> </CODE>;;<BR><CODE>- : unit = ()</CODE><BR>

</PRE>

From the last obtained value, nothing is printed: it is the value
<EM>()</EM> of type <I>unit</I>.<BR>
<BR>
One cannot build a format using values of type <I>string</I>: 


<PRE><BR># <B>let</B><CODE> </CODE>f<CODE> </CODE>d<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE>Printf.printf<CODE> </CODE><TT>(</TT>d<CODE>^</CODE>d<TT>)</TT>;;<BR><CODE>Characters 27-30:</CODE><BR><CODE>This expression has type string but is here used with type</CODE><BR><CODE>  ('a, out_channel, unit) format</CODE><BR>

</PRE>
<BR>
<BR>
The compiler cannot know the value of the string passed as an argument.
It thus cannot know the type that instantiates the <I>'a</I> parameter
of type <TT>format</TT>.<BR>
<BR>
On the other hand, strings are physically modifiable values,
it would thus be possible to replace, for example, the <EM>%d</EM> part
with another letter, thus dynamically changing the print format.
This conflicts with the static generation of the conversion function.<BR>
<BR>

<H4> <TT>Digest</TT> Module</H4>
<A NAME="@fonctions279"></A>
<A NAME="@concepts153"></A>
<A NAME="@concepts154"></A>
<A NAME="@concepts155"></A>
<A NAME="@fonctions280"></A>
A hash function converts a character string of unspecified size
into a character string of fixed length, most often smaller.
Hashing functions return a fingerprint (digest)
of their entry. <BR>
<BR>
Such functions are used for the construction of hash tables, as in the
<TT>Hashtbl</TT> module, permitting one to rapidly test if an element
is a member of such a table by directly accessing the fingerprint.
For example the function <TT>f_mod_n</TT>,
that generates the modulo <I>n</I> sum of the ASCII codes of the
characters in a string, is a hashing function. If one creates an
<I>n</I> by <I>n</I> table to arrange the strings, from the fingerprint one obtains
direct access. Nevertheless two strings can return the same fingerprint.
In the case of collisions, one adds to the hash table an extension
to store these elements. If there are too many collisions,
then access to the hash table is not very effective. If the fingerprint
has a length of <I>n</I> bits, then the probability of collision between two
different strings is 1/2<SUP><FONT SIZE=2><I>n</I></FONT></SUP>.<BR>
<BR>
A non-reversible hash function has a very weak probability of
collision. It is thus difficult, given a fingerprint, to construct
a string with this fingerprint. The preceding function <TT>f_mod_n</TT>
is not, based on the evidence, such a function. One way hash functions
permit the authentification of a string, that it is for some text sent
over the Internet, a file, etc.<BR>
<BR>
The <TT>Digest</TT> module uses the MD5 algorithm, short for 
Message Digest 5. It returns a 128 bit fingerprint. Although
the algorithm is public, it is impossible (today) to carry out a
reconstruction from a fingerprint. This module defines the 
<I>Digest.t</I> type as an abbreviation of the <I>string</I> type. The
figure <A HREF="book-ora076.html#fig-mod-digest">8.3</A> details the main functions of this module.<BR>
<BR>
<A NAME="@fonctions281"></A>
<A NAME="@fonctions282"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>string</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; t</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>returns the fingerprint of a string</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>file</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; t</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>returns the fingerprint of a file</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.3: Functions of the <TT>Digest</TT> module.</DIV><BR>

<A NAME="fig-mod-digest"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>We use the <TT>string</TT> function in the following example on a small
string and on a large one built from the first. The fingerprint is always
of fixed length.


<PRE><BR># <B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"The small cat is dead..."</CODE>;;<BR><CODE>val s : string = "The small cat is dead..."</CODE><BR># Digest.string<CODE> </CODE>s;;<BR><CODE>- : Digest.t = "xr6\127\171(\134=\238`\252F\028\t\210$"</CODE><BR><BR># <B>let</B><CODE> </CODE>r<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>s<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE>=</CODE><CODE>1</CODE><CODE> </CODE><B>to</B><CODE> </CODE><CODE>1</CODE><CODE>0</CODE><CODE>0</CODE><CODE> </CODE><B>do</B><CODE> </CODE>r<CODE>:=</CODE><CODE> </CODE>s<CODE>^</CODE><CODE> </CODE><CODE>!</CODE>r<CODE> </CODE><B>done</B>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Digest.string<CODE> </CODE><CODE>!</CODE>r;;<BR><CODE>- : Digest.t = "\232\197|C]\137\180{&gt;\224QX\155\131D\225"</CODE><BR>

</PRE>
<BR>
<BR>
The creation of a fingerprint for a program allows one to guarantee the
contents and thus avoids the use of a bad version. For example, when code
is dynamically loaded (see page
<A HREF="book-ora077.html#sec-mod-dynlink">??</A>), a fingerprint is used to select the binary file
to load.


<PRE><BR># Digest.file<CODE> </CODE><CODE>"basic.ml"</CODE><CODE> </CODE>;;<BR><CODE>- : Digest.t = "\179\026\191\137\157Ly|^w7\183\164:\167q"</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="toc106"></A>
<H3> Persistence</H3>
<A NAME="sec-persist"></A>
<A NAME="@concepts156"></A>
<A NAME="@concepts157"></A>
Persistence is the conservation of a value outside the running
execution of a program. This is the case when one writes a value in a file.
This value is thus accessible to any program that has access to the file.
Writing and reading persistent values requires the definition of a format
for representing the coding of data. In effect, one must know how to go
from a complex structure stored in memory, such as a binary tree, to a 
linear structure, a list of bytes, stored in a file.
This is why the coding of persistent values is called linearization
<A NAME="text17" HREF="book-ora081.html#note17"><SUP><FONT SIZE=2>1</FONT></SUP></A>. <BR>
<BR>

<H4> Realization and Difficulties of Linearization</H4>
<A NAME="@concepts158"></A>
The implementation of a mechanism for the linearization of data structures
requires choices and presents difficulties that we describe below.
<UL>
<LI>
<B>read-write of data structures.</B>
Since memory can always be viewed as a vector of words, one value can
always correspond to the memory that it occupies, leaving us to
preserve the useful part by then compacting the value.

<LI><B>share or copy.</B>
Must the linearization of a data structure conserve sharing?
Typically a binary tree having two identical children (in the sense of
physical equality) can indicate, for the second child, that it has already
saved the first. This characteristic influences the size of the saved value
and the time taken to do it. On the other hand, in the presence of
physically modifiable values, this could change the behavior of 
this value after a recovery depending on whether or not sharing was
conserved.

<LI><B>circular structures.</B>
In the case of a circular value, linearization without sharing is likely
to loop. It will be necessary to conserve sharing.

<LI><B>functional values.</B>
Functional values, or closures, are composed of an environment part and
a code part. The code part corresponds to the entry point (address) of
the code to execute. What must thus be done with code?
It is possible to uniquely store this address, but thus only the same
program will find the correct meaning of this address. It is also
possible to save the list of machine instructions of this function,
but that would require having a mechanism to dynamically load code.

<LI><B>guaranteeing the type when reloading.</B>
This is the main difficulty of this mechanism. Static typing guarantees
that typed values will not generate type errors at execution time.
But this is not true except for values belonging to the program
during the course of execution. What type can one give to a value outside
the program, that was not seen by the type verifier? Just to verify that
the re-read value has the
monomorphic type generated by the compiler, the type would have to be
transmitted at the moment the value was saved, then the type would have
to be checked when the value was loaded. Additionally, a mechanism
to manage the versions of types would be needed to be safe in case
a type is redeclared in a program.
</UL>
<H4> <TT>Marshal</TT> Module</H4>
<A NAME="mod-marshal"></A>
<A NAME="@fonctions283"></A>
<A NAME="@concepts159"></A>
The linearization mechanism in the <TT>Marshal</TT> module allows you
to choose to keep or discard the sharing of values. It also allows for
the use of closures, but in this case, only the 
pointer to the code is saved.<BR>
<BR>
This module is mainly comprised of functions for linearization via a channel
or a string, and functions for recovery via a channel or a string.
The linearization functions are
parameterizable. The following type declares two possible options:
<PRE>
type external_flag = 
  No_sharing
| Closures;;
</PRE>The <TT>No_sharing</TT> constant constructor
indicates that the sharing of values is not to be preserved, though the default is
to keep sharing. The <TT>Closures</TT> constructor allows the use of closures
while conserving its pointer to the code. Its absence will raise an exception
if one tries to store a functional value.


<H3> Warning </H3> <HR>

The <TT>Closures</TT> constructor is inoperative in interactive mode. It can
only be used in command line mode.


<HR>

<BR>
<BR>
<A NAME="@fonctions284"></A><A NAME="@fonctions285"></A><A NAME="@fonctions286"></A><A NAME="@fonctions287"></A><A NAME="@fonctions288"></A>The reading and writing functions in this module are gathered in figure
<A HREF="book-ora076.html#fig-mod-marshal">8.4</A>.<BR>
<BR>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>to_channel</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>out_channel -&gt; 'a -&gt; extern_flag list -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>to_string</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>'a -&gt; extern_flag list -&gt; string</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>to_buffer</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; int -&gt; int -&gt; 'a -&gt; extern_flag list -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>from_channel</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>in_channel -&gt; 'a</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>from_string</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; int -&gt; 'a</I></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.4: Functions of the <TT>Marshal</TT> module.</DIV><BR>

<A NAME="fig-mod-marshal"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The <TT>to_channel</TT> function takes an output channel, a value,
and a list of options and writes the value to the channel. The
<TT>to_string</TT> function produces a string corresponding to the
linearized value, whereas <TT>to_buffer</TT> accomplishes the same
task by modifying part of a string passed as an argument.
The <TT>from_channel</TT> function reads a linearized value from a
channel and returns it. The <TT>from_string</TT> variant
takes as input a string and the position of the first character to read
in the string. Several linearized values can be stored in the same file
or in the same string. For a file, they can be read sequentially.
For a string, one must specify the right offset from the beginning of
the string to decode the desired value.<BR>
<BR>


<PRE><BR># <B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Marshal.to_string<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE>2</CODE>;<CODE>3</CODE>;<CODE>4</CODE><CODE>]</CODE><CODE> </CODE>[]<CODE> </CODE><B>in</B><CODE> </CODE>String.sub<CODE> </CODE>s<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>1</CODE><CODE>0</CODE>;;<BR><CODE>- : string = "\132\149\166\190\000\000\000\t\000\000"</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Warning </H3> <HR>

Using this module one loses the safety of static typing
(see <I>infra</I>, page <A HREF="book-ora076.html#subsubsec-pb-typage">??</A>).


<HR>

<BR>
<BR>
Loading a persistent object creates a value of indeterminate type:


<PRE><BR># <B>let</B><CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Marshal.from_string<CODE> </CODE><TT>(</TT>Marshal.to_string<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>4</CODE><CODE>]</CODE><CODE> </CODE>[]<TT>)</TT><CODE> </CODE><CODE>0</CODE>;;<BR><CODE>val x : '_a = &lt;poly&gt;</CODE><BR>

</PRE>

This indetermination is denoted in Objective CAML by the weakly typed variable
<I>'_a</I>. You should specify the expected type:


<PRE><BR># <B>let</B><CODE> </CODE>l<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT>Marshal.to_string<CODE> </CODE><CODE>[</CODE><CODE>1</CODE>;<CODE> </CODE><CODE>2</CODE>;<CODE> </CODE><CODE>3</CODE>;<CODE> </CODE><CODE>4</CODE><CODE>]</CODE><CODE> </CODE>[]<TT>)</TT><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Marshal.from_string<CODE> </CODE>s<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>int<CODE> </CODE>list<TT>)</TT><CODE> </CODE>;;<BR><CODE>val l : int list = [1; 2; 3; 4]</CODE><BR>

</PRE>

We return to this topic on page <A HREF="book-ora076.html#subsubsec-pb-typage">??</A>.<BR>
<BR>


<H3> Note </H3> <HR>

The <TT>output_value</TT> function of the preloaded library
corresponds to calling <TT>to_channel</TT> with an empty list of options.
The <TT>input_value</TT> function in the <TT>Pervasives</TT> module
directly calls the <TT>from_channel</TT> function. These functions were
kept for compatibility with old programs.


<HR>

<BR>
<BR>

<H4> Example: Backup Screens</H4>
We want to save the bitmap, represented as a matrix of colors,
of the whole screen. The <TT>save_screen</TT> function recovers the
bitmap, converts it to a table of colors and saves it in a file
whose name is passed as a parameter.


<PRE><BR># <B>let</B><CODE> </CODE>save_screen<CODE> </CODE>name<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.get_image<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>(</TT>Graphics.size_x<CODE> </CODE>()<TT>)</TT><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Graphics.size_y<CODE> </CODE>()<TT>)</TT><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>j<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.dump_image<CODE> </CODE>i<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>oc<CODE> </CODE><CODE>=</CODE><CODE> </CODE>open_out<CODE> </CODE>name<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>output_value<CODE> </CODE>oc<CODE> </CODE>j;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>close_out<CODE> </CODE>oc;;<BR><CODE>val save_screen : string -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The <TT>load_screen</TT> function does the reverse operation.
It opens the file whose name is passed as a parameter, restores the value
stored inside, converts this color matrix into a bitmap, then displays the
bitmap.


<PRE><BR># <B>let</B><CODE> </CODE>load_screen<CODE> </CODE>name<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>ic<CODE> </CODE><CODE>=</CODE><CODE> </CODE>open_in<CODE> </CODE>name<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>image<CODE> </CODE><CODE>=</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>input_value<CODE> </CODE>ic<TT>)</TT><CODE> </CODE><CODE>:</CODE><CODE> </CODE>Graphics.color<CODE> </CODE>array<CODE> </CODE>array<TT>)</TT><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>close_in<CODE> </CODE>ic;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.close_graph();<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.open_graph<CODE> </CODE><TT>(</TT><CODE>" "</CODE><CODE>^</CODE><TT>(</TT>string_of_int<TT>(</TT>Array.length<CODE> </CODE>image<CODE>.</CODE><TT>(</TT><CODE>0</CODE><TT>)</TT><TT>)</TT><TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>^</CODE><CODE>"x"</CODE><CODE>^</CODE><TT>(</TT>string_of_int<TT>(</TT>Array.length<CODE> </CODE>image<TT>)</TT><TT>)</TT><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>image2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Graphics.make_image<CODE> </CODE>image<CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Graphics.draw_image<CODE> </CODE>image2<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>0</CODE>;<CODE> </CODE>image2<CODE> </CODE>;;<BR><CODE>val load_screen : string -&gt; Graphics.image = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>


<H3> Warning </H3> <HR>

Abstract typed values cannot be made persistent.


<HR>


It is for this reason that the preceding example does not use the abstract
<I>Graphics.image</I> type, but instead uses the concrete
<I>color array array</I> type. The abstraction of types is presented in
chapter <A HREF="index.html#chap-PM">14</A>.<BR>
<BR>

<H4> Sharing</H4>
<A NAME="@concepts160"></A>
The loss of sharing in a data structure can make the structure
completely lose its intended behavior. Let us revisit the example of
the symbol generator from page
<A HREF="book-ora039.html#subsec-gensym">??</A>. For whatever reason, we want to save the
functional values <TT>new_s</TT> and <TT>reset_s</TT>,
and thereafter use the current value of their common counter.
We thus write the following program:


<PRE>
<CODE> </CODE><BR># <B>let</B><CODE> </CODE>reset_s<CODE>,</CODE>new_s<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>c<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><B>function</B><CODE> </CODE>()<CODE> </CODE>-&gt;<CODE> </CODE>c<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>,</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE> </CODE><B>function</B><CODE> </CODE>s<CODE> </CODE>-&gt;<CODE> </CODE><CODE> </CODE>c<CODE>:=!</CODE>c<CODE>+</CODE><CODE>1</CODE>;<CODE> </CODE>s<CODE>^</CODE><TT>(</TT>string_of_int<CODE> </CODE><CODE>!</CODE>c<TT>)</TT><CODE> </CODE><TT>)</TT><CODE> </CODE>;;<BR><BR># <B>let</B><CODE> </CODE>save<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Marshal.to_string<CODE> </CODE><TT>(</TT>new_s<CODE>,</CODE>reset_s<TT>)</TT><CODE> </CODE><CODE>[</CODE>Marshal<CODE>.</CODE>Closures;Marshal<CODE>.</CODE>No_sharing<CODE>]</CODE><CODE> </CODE>;;<BR><BR># <B>let</B><CODE> </CODE><TT>(</TT>new_s1<CODE>,</CODE>reset_s1<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><TT>(</TT>Marshal.from_string<CODE> </CODE>save<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE><TT>(</TT><TT>(</TT>string<CODE> </CODE>-&gt;<CODE> </CODE>string<CODE> </CODE><TT>)</TT><CODE> </CODE><CODE>*</CODE><CODE> </CODE><TT>(</TT>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><BR># <CODE>(* 1 *)</CODE><BR><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"new_s : \%s\n"</CODE><CODE> </CODE><TT>(</TT>new_s<CODE> </CODE><CODE>"X"</CODE><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"new_s : \%s\n"</CODE><CODE> </CODE><TT>(</TT>new_s<CODE> </CODE><CODE>"X"</CODE><TT>)</TT>;<BR><CODE> </CODE><CODE>(* 2 *)</CODE><BR><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"new_s1 : \%s\n"</CODE><CODE> </CODE><TT>(</TT>new_s1<CODE> </CODE><CODE>"X"</CODE><TT>)</TT>;<CODE> </CODE><BR><CODE> </CODE><CODE>(* 3 *)</CODE><BR><CODE> </CODE>reset_s1();<CODE> </CODE><BR><CODE> </CODE>Printf.printf<CODE> </CODE><CODE>"new_s1 (after reset_s1) : \%s\n"</CODE><CODE> </CODE><TT>(</TT>new_s1<CODE> </CODE><CODE>"X"</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>Characters 148-154:</CODE><BR><CODE>Unbound value new_s1</CODE><BR>

</PRE>
<BR>
<BR>
The first two outputs in <CODE>(* 1 *)</CODE> comply with our intent.
The output obtained in <CODE>(* 2 *)</CODE> after re-reading 
the closures also appears correct (after <CODE>X2</CODE>
comes <CODE>X3</CODE>). But, in fact, the sharing of the <TT>c</TT> counter
between the re-read functions <TT>new_s1</TT> and <TT>reset_s1</TT>
is lost, as the output of <CODE>X4</CODE> attests that one of them 
set the counter to zero. Each closure has a copy of the counter and
the call to <TT>reset_s1</TT> does not reset the
<TT>new_s1</TT> counter to zero. Thus we should not have used the <TT>No_sharing</TT>
option during the linearization.<BR>
<BR>
It is generally necessary to conserve sharing. Nevertheless in certain
cases where execution speed is important, the absence of sharing
speeds up the process of saving. The following example demonstrates a
function that copies a matrix. In this case it might be preferable to break
the sharing:


<PRE><BR># <B>let</B><CODE> </CODE>copy_mat_f<CODE> </CODE><TT>(</TT>m<CODE> </CODE><CODE>:</CODE><CODE> </CODE>float<CODE> </CODE>array<CODE> </CODE>array<TT>)</TT><CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Marshal.to_string<CODE> </CODE>m<CODE> </CODE><CODE>[</CODE>Marshal<CODE>.</CODE>No_sharing<CODE>]</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT>Marshal.from_string<CODE> </CODE>s<CODE> </CODE><CODE>0</CODE><CODE> </CODE><CODE>:</CODE><CODE> </CODE>float<CODE> </CODE>array<CODE> </CODE>array<TT>)</TT>;;<BR><CODE>val copy_mat_f : float array array -&gt; float array array = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
One can also use it to create a matrix without sharing:


<PRE><BR># <B>let</B><CODE> </CODE>create_mat_f<CODE> </CODE>n<CODE> </CODE>m<CODE> </CODE>v<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>m<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Array.create<CODE> </CODE>n<CODE> </CODE><TT>(</TT>Array.create<CODE> </CODE>m<CODE> </CODE>v<TT>)</TT><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>copy_mat_f<CODE> </CODE>m;;<BR><CODE>val create_mat_f : int -&gt; int -&gt; float -&gt; float array array = &lt;fun&gt;</CODE><BR># <B>let</B><CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE>create_mat_f<CODE> </CODE><CODE>3</CODE><CODE> </CODE><CODE>4</CODE><CODE> </CODE><CODE>3</CODE><CODE>.</CODE><CODE>1</CODE><CODE>4</CODE>;;<BR><CODE>val a : float array array =</CODE><BR><CODE>  [|[|3.14; 3.14; 3.14; 3.14|]; [|3.14; 3.14; 3.14; 3.14|];</CODE><BR><CODE>    [|3.14; 3.14; 3.14; 3.14|]|]</CODE><BR># a<CODE>.</CODE><TT>(</TT><CODE>1</CODE><TT>)</TT><CODE>.</CODE><TT>(</TT><CODE>2</CODE><TT>)</TT><CODE> </CODE><CODE>&lt;-</CODE><CODE> </CODE><CODE>6</CODE><CODE>.</CODE><CODE>2</CODE><CODE>8</CODE>;;<BR><CODE>- : unit = ()</CODE><BR># a;;<BR><CODE>- : float array array =</CODE><BR><CODE>[|[|3.14; 3.14; 3.14; 3.14|]; [|3.14; 3.14; 6.28; 3.14|];</CODE><BR><CODE>  [|3.14; 3.14; 3.14; 3.14|]|]</CODE><BR>

</PRE>
<BR>
<BR>
Which is a more common behavior than that of
<TT>Array.create</TT>, and resembles that of
<TT>Array.create_matrix</TT>.<BR>
<BR>

<H4> Size of Values</H4>
It may be useful to know the size of a persistent value. If sharing
is conserved, this size also reflects the amount of memory occupied by
a value. Although the encoding sometimes optimizes the size
of atomic values<A NAME="text18" HREF="book-ora081.html#note18"><SUP><FONT SIZE=2>2</FONT></SUP></A>, knowing
the size of their respective encodings permits us to compare different
implementations of a data structure.
In addition, for programs that will never stop themselves, like
embedded systems or even network servers; watching the size of
data structures can help detect memory leaks. The <TT>Marshal</TT>
module has two functions to calculate the size of a constant. They are
described in figure <A HREF="book-ora076.html#fig-marsh-size">8.5</A>.
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>header_size</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>data_size</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; int -&gt; int</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>total_size</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; int -&gt; int</I></TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.5: Size functions of <TT>Marshal</TT>.</DIV><BR>

<A NAME="fig-marsh-size"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>
The total size of a persistent value is the same as the size of its
data structures plus the size of its
header.<BR>
<BR>
Below is a small example of the use of MD5 encoding to compare
two representations of binary trees:


<PRE><BR># <B>let</B><CODE> </CODE>size<CODE> </CODE>x<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Marshal.data_size<CODE> </CODE><TT>(</TT>Marshal.to_string<CODE> </CODE>x<CODE> </CODE>[]<TT>)</TT><CODE> </CODE><CODE>0</CODE>;;<BR><CODE>val size : 'a -&gt; int = &lt;fun&gt;</CODE><BR># <B>type</B><CODE> </CODE><I>'a</I><CODE> </CODE>bintree1<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Empty1<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Node1<CODE> </CODE><B>of</B><CODE> </CODE><I>'a</I><CODE> </CODE><CODE>*</CODE><CODE> </CODE><I>'a</I><CODE> </CODE>bintree1<CODE> </CODE><CODE>*</CODE><CODE> </CODE><I>'a</I><CODE> </CODE>bintree1<CODE> </CODE>;;<BR><CODE>type 'a bintree1 = | Empty1 | Node1 of 'a * 'a bintree1 * 'a bintree1</CODE><BR># <B>let</B><CODE> </CODE>s1<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>Node1<TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE> </CODE>Node1<TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>Node1<TT>(</TT><CODE>0</CODE><CODE>,</CODE><CODE> </CODE>Empty1<CODE>,</CODE><CODE> </CODE>Empty1<TT>)</TT><CODE>,</CODE><CODE> </CODE>Empty1<TT>)</TT><CODE>,</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Node1<TT>(</TT><CODE>3</CODE><CODE>,</CODE><CODE> </CODE>Empty1<CODE>,</CODE><CODE> </CODE>Empty1<TT>)</TT><TT>)</TT><CODE> </CODE>;;<BR><CODE>val s1 : int bintree1 =</CODE><BR><CODE>  Node1</CODE><BR><CODE>   (2, Node1 (1, Node1 (0, Empty1, Empty1), Empty1),</CODE><BR><CODE>    Node1 (3, Empty1, Empty1))</CODE><BR># <B>type</B><CODE> </CODE><I>'a</I><CODE> </CODE>bintree2<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE>Empty2<CODE> </CODE><CODE>|</CODE><CODE> </CODE>Leaf2<CODE> </CODE><B>of</B><CODE> </CODE><I>'a</I><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Node2<CODE> </CODE><B>of</B><CODE> </CODE><I>'a</I><CODE> </CODE><CODE>*</CODE><CODE> </CODE><I>'a</I><CODE> </CODE>bintree2<CODE> </CODE><CODE>*</CODE><CODE> </CODE><I>'a</I><CODE> </CODE>bintree2<CODE> </CODE>;;<BR><CODE>type 'a bintree2 =</CODE><BR><CODE>  | Empty2</CODE><BR><CODE>  | Leaf2 of 'a</CODE><BR><CODE>  | Node2 of 'a * 'a bintree2 * 'a bintree2</CODE><BR># <B>let</B><CODE> </CODE>s2<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE>Node2<TT>(</TT><CODE>2</CODE><CODE>,</CODE><CODE> </CODE>Node2<TT>(</TT><CODE>1</CODE><CODE>,</CODE><CODE> </CODE>Leaf2<CODE> </CODE><CODE>0</CODE><CODE>,</CODE><CODE> </CODE>Empty2<TT>)</TT><CODE>,</CODE><CODE> </CODE>Leaf2<CODE> </CODE><CODE>3</CODE><TT>)</TT><CODE> </CODE>;;<BR><CODE>val s2 : int bintree2 = Node2 (2, Node2 (1, Leaf2 0, Empty2), Leaf2 3)</CODE><BR># <B>let</B><CODE> </CODE>s1<CODE>,</CODE><CODE> </CODE>s2<CODE> </CODE><CODE>=</CODE><CODE> </CODE>size<CODE> </CODE>s1<CODE>,</CODE><CODE> </CODE>size<CODE> </CODE>s2<CODE> </CODE>;;<BR><CODE>val s1 : int = 13</CODE><BR><CODE>val s2 : int = 9</CODE><BR>

</PRE>

The values given by the <TT>size</TT> function reflect well the
intuition that one might have of the size of <TT>s1</TT> and
<TT>s2</TT>. <BR>
<BR>

<H4> Typing Problem</H4><A NAME="subsubsec-pb-typage"></A>
<A NAME="@concepts161"></A>
The real problem with persistent values is that it is possible to
break the type system of Objective CAML. The creation functions return
a monomorphic type (<I>unit</I> or <I>string</I>). On the other
hand unmarshalling functions return a polymorphic type <I>'a</I>.
From the point of view of types, you can do anything with a persistent
value. Here is the usage that can be done with it
(see chapter <A HREF="index.html#chap-PF">2</A>, page
<A HREF="book-ora018.html#sec-retourpoly">??</A>): create a function
<TT>magic_copy</TT> of type <I>'a -&gt; 'b</I>.


<PRE><BR># <B>let</B><CODE> </CODE>magic_copy<CODE> </CODE>a<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>s<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Marshal.to_string<CODE> </CODE>a<CODE> </CODE><CODE>[</CODE>Marshal<CODE>.</CODE>Closures<CODE>]</CODE><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>Marshal.from_string<CODE> </CODE>s<CODE> </CODE><CODE>0</CODE>;;<BR><CODE>val magic_copy : 'a -&gt; 'b = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
The use of such a function causes a brutal halt in the execution
of the program.
<PRE>
#  (magic_copy 3 : float) +. 3.1;;
Segmentation fault
</PRE>In interactive mode (under Linux), we even leave the toplevel
(interactive) loop with a system error signal corresponding
to a memory violation.<BR>
<BR>
<A NAME="toc107"></A>
<H3> Interface with the System</H3>
<A NAME="sec-mod-sys"></A>
<A NAME="@concepts162"></A>
The standard library has six system interface modules:
<UL>
<LI>
 module <TT>Sys</TT>: for communication between the operating system
and the program;

<LI> module <TT>Arg</TT>: to analyze parameters passed to the program
from the command line; 

<LI> module <TT>Filename</TT>: operations on file names

<LI> module <TT>Printexc</TT>: for the interception and printing
of exceptions;

<LI> module <TT>Gc</TT>: to control the mechanism that automatically
deallocates memory, described in chapter <A HREF="index.html#chap-GC">9</A>; 

<LI> module <TT>Callback</TT>: to call Objective CAML functions from C,
described in chapter <A HREF="index.html#chap-interop">12</A>. 
</UL>
The first four modules are described below.<BR>
<BR>

<H4> Module <TT>Sys</TT></H4>
<A NAME="@fonctions289"></A>
This module provides quite useful functions for communication with
the operating system, such as handling the signals received by
a program. The values in figure <A HREF="book-ora076.html#fig-sys-info">8.6</A> contain information
about the system.<BR>
<BR>
<A NAME="@fonctions290"></A>
<A NAME="@fonctions291"></A>
<A NAME="@fonctions292"></A>
<A NAME="@fonctions293"></A>
<A NAME="@fonctions294"></A>
<A NAME="@fonctions295"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>OS_type</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>type of system</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>interactive</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>bool ref</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>true if executing at the toplevel</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>word_size</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>size of a word (32 or 64 bits)</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>max_string_length</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>maximum size of a string</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>max_array_length</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>int</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>maximum size of a vector</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>time</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>unit -&gt; float</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  VALIGN=top ALIGN=left>gives the time in seconds since the start of
the program</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.6: Information about the system.</DIV><BR>

<A NAME="fig-sys-info"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE><A NAME="@concepts163"></A>Communication between the program and the system can go through the command
line, the value of an environmental variable, or through running
another program. These functions are described
in figure <A HREF="book-ora076.html#fig-sys-com">8.7</A>.
<A NAME="@fonctions296"></A>
<A NAME="@fonctions297"></A>
<A NAME="@fonctions298"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>argv</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string array</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>contains the vector of parameters</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>getenv</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; string</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>retrieves the value of a variable</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>command</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; int</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>executes the command passed as an argument</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.7: Communication with the system.</DIV><BR>

<A NAME="fig-sys-com"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The functions of the figure <A HREF="book-ora076.html#fig-sys-fichiers">8.8</A> allow us to 
navigate in the file hierarchy.
<A NAME="@fonctions299"></A>
<A NAME="@fonctions300"></A>
<A NAME="@fonctions301"></A>
<A NAME="@fonctions302"></A>
<A NAME="@fonctions303"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>file_exists</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; bool</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>returns <TT>true</TT> if the file exists</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>remove</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>destroys a file</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>rename</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; string -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>renames a file</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>chdir</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>string -&gt; unit</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>change the current directory</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>getcwd</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>unit -&gt; string</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>returns the name of the current directory</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.8: File manipulation.</DIV><BR>

<A NAME="fig-sys-fichiers"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>Finally, the management of signals will be described in the chapter on
system programming (<A HREF="index.html#chap-PS">18</A>). <BR>
<BR>
Here is a small program that revisits the example of saving a graphics
window as an array of colors. The <TT>main</TT> function verifies
that it is not started from the interactive loop, then reads from the
command line the names of files to display, then tests if they exist, then
displays them (with the <TT>load_screen</TT> function). We wait for a key to be
pressed between displaying two images.


<PRE><BR># <B>let</B><CODE> </CODE>main<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>not<CODE> </CODE><TT>(</TT><CODE>!</CODE>Sys.interactive<TT>)</TT><CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>for</B><CODE> </CODE>i<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>0</CODE><CODE> </CODE><B>to</B><CODE> </CODE>Array.length<TT>(</TT>Sys.argv<TT>)</TT><CODE> </CODE><CODE>-</CODE><CODE>1</CODE><CODE> </CODE><B>do</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>name<CODE> </CODE><CODE>=</CODE><CODE> </CODE>Sys.argv<CODE>.</CODE><TT>(</TT>i<TT>)</TT><CODE> </CODE><B>in</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>if</B><CODE> </CODE>Sys.file_exists<CODE> </CODE>name<CODE> </CODE><B>then</B><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>begin</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<TT>(</TT>load_screen<CODE> </CODE>name<TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE>ignore<TT>(</TT>Graphics.read_key<TT>)</TT><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>end</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><B>done</B>;;<BR><CODE>val main : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>

<H4> Module <TT>Arg</TT></H4>
<A NAME="sec-module-arg"></A>
<A NAME="@fonctions304"></A>
The <TT>Arg</TT> module defines a small syntax for command line
arguments. With this module, you can parse arguments and associate actions
with them.
<A NAME="@concepts164"></A>
The various elements of the command line are separated by one or more
spaces. They are the values stored in the <TT>Sys.argv</TT> array.
In the syntax provided by
<TT>Arg</TT>, certain elements are distinguished by starting with the
minus character (<TT>-</TT>). These are called command line
keywords or switches. One can associate a specific action with a keyword
or take as an argument a value of type <I>string</I>, <I>int</I>
or <I>float</I>. The value of these arguments is initialized with
the value found on the command line just after the keyword.
In this case one can call a function that converts character strings
into the expected type. The other elements on the command line are called
anonymous arguments. One associates an action with them that takes
their value as an argument. An undefined option causes the display
of some short documentation on the command line. The documentation's
contents are defined by the user.<BR>
<BR>
The actions associated with keywords are encapsulated in the type:


<PRE><BR><B>type</B><CODE> </CODE>spec<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Unit<CODE> </CODE><B>of</B><CODE> </CODE><TT>(</TT>unit<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Call the function with unit argument*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Set<CODE> </CODE><B>of</B><CODE> </CODE>bool<CODE> </CODE>ref<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Set the reference to true*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Clear<CODE> </CODE><B>of</B><CODE> </CODE>bool<CODE> </CODE>ref<CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Set the reference to false*)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>String<CODE> </CODE><B>of</B><CODE> </CODE><TT>(</TT>string<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><CODE> </CODE><CODE>(* Call the function with a string </CODE><BR><CODE>                                argument *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Int<CODE> </CODE><B>of</B><CODE> </CODE><TT>(</TT>int<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Call the function with an int </CODE><BR><CODE>                                argument *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Float<CODE> </CODE><B>of</B><CODE> </CODE><TT>(</TT>float<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Call the function with a float </CODE><BR><CODE>                                argument *)</CODE><BR><CODE> </CODE><CODE> </CODE><CODE>|</CODE><CODE> </CODE>Rest<CODE> </CODE><B>of</B><CODE> </CODE><TT>(</TT>string<CODE> </CODE>-&gt;<CODE> </CODE>unit<TT>)</TT><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>(* Stop interpreting keywords and call the</CODE><BR><CODE>                                function with each remaining argument*)</CODE><BR>

</PRE>
<BR>
<BR>
<A NAME="@fonctions305"></A>
The command line parsing function is:


<PRE><BR># Arg.parse<CODE> </CODE>;;<BR><CODE>- : (string * Arg.spec * string) list -&gt; (string -&gt; unit) -&gt; string -&gt; unit =</CODE><BR><CODE>&lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
Its first argument is a list of triples of the form
<EM>(key, spec, doc)</EM> such that:
<UL>
<LI>
<EM>key</EM> is a character string corresponding to the keyword.
It starts with the reserved character <TT>'_'</TT>.

<LI><EM>spec</EM> is a value of type <I>spec</I> specifying the
action associated with <EM>key</EM>.

<LI><EM>doc</EM> is a character string describing the option
<EM>key</EM>. It is displayed upon a syntax error.
</UL>The second argument is the function to process the anonymous 
command line arguments.
The last argument is a character string displayed at the beginning of
the command line documentation.<BR>
<BR>
The <TT>Arg</TT> module also includes:
<UL>
<LI>
<TT>Bad</TT>: an exception taking as its argument a character string.
It can be used by the processing functions.

<LI><TT>usage</TT>: of type <I>(string * Arg.spec * string)
list -&gt; string -&gt; unit</I>, this function displays the command line
documentation. One preferably provides it with the same arguments as
those of <TT>parse</TT>. 

<LI><TT>current</TT>: of type <I>int ref</I> that contains a
reference to the current value of the index in the <TT>Sys.argv</TT> array. 
One can therefore modify this value if necessary.
</UL>By way of an example, we show a function <TT>read_args</TT> that
initializes the configuration of 
the Minesweeper game seen in chapter <A HREF="book-ora059.html#sec-demin">6</A>, page <A HREF="book-ora059.html#sec-demin">??</A>.
The possible options will be
<TT>-col</TT>, <TT>-lin</TT> and <TT>-min</TT>. They will be followed
by an integer indicating, respectively: the number of columns,
the number of lines and the number of mines desired. These values must
not be less than the default values,
respectively <TT>10</TT>, <TT>10</TT> and <TT>15</TT>.<BR>
<BR>
The processing functions are:


<PRE><BR># <B>let</B><CODE> </CODE>set_nbcols<CODE> </CODE>cf<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cf<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>{!</CODE>cf<CODE> </CODE><B>with</B><CODE> </CODE>nbcols<CODE> </CODE><CODE>=</CODE><CODE> </CODE>n}<CODE> </CODE>;;<BR># <B>let</B><CODE> </CODE>set_nbrows<CODE> </CODE>cf<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cf<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>{!</CODE>cf<CODE> </CODE><B>with</B><CODE> </CODE>nbrows<CODE> </CODE><CODE>=</CODE><CODE> </CODE>n}<CODE> </CODE>;;<BR># <B>let</B><CODE> </CODE>set_nbmines<CODE> </CODE>cf<CODE> </CODE>n<CODE> </CODE><CODE>=</CODE><CODE> </CODE>cf<CODE> </CODE><CODE>:=</CODE><CODE> </CODE><CODE>{!</CODE>cf<CODE> </CODE><B>with</B><CODE> </CODE>nbmines<CODE> </CODE><CODE>=</CODE><CODE> </CODE>n}<CODE> </CODE>;;<BR>

</PRE>
<BR>
<BR>
All three are of type <I>config ref -&gt; int -&gt; unit</I>.
The command line parsing function can be written: 


<PRE><BR># <B>let</B><CODE> </CODE>read_args()<CODE> </CODE><CODE>=</CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>cf<CODE> </CODE><CODE>=</CODE><CODE> </CODE>ref<CODE> </CODE>default_config<CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>speclist<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE>[</CODE><TT>(</TT><CODE>"-col"</CODE><CODE>,</CODE><CODE> </CODE>Arg<CODE>.</CODE>Int<CODE> </CODE><TT>(</TT>set_nbcols<CODE> </CODE>cf<TT>)</TT><CODE>,</CODE><CODE> </CODE><CODE>"number of columns (&gt;=10)"</CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>"-lin"</CODE><CODE>,</CODE><CODE> </CODE>Arg<CODE>.</CODE>Int<CODE> </CODE><TT>(</TT>set_nbrows<CODE> </CODE>cf<TT>)</TT><CODE>,</CODE><CODE> </CODE><CODE>"number of lines (&gt;=10)"</CODE><TT>)</TT>;<BR><CODE> </CODE><CODE> </CODE><CODE> </CODE><CODE> </CODE><TT>(</TT><CODE>"-min"</CODE><CODE>,</CODE><CODE> </CODE>Arg<CODE>.</CODE>Int<CODE> </CODE><TT>(</TT>set_nbmines<CODE> </CODE>cf<TT>)</TT><CODE>,</CODE><CODE> </CODE><CODE>"number of mines (&gt;=15)"</CODE><TT>)</TT><CODE>]</CODE><BR><CODE> </CODE><CODE> </CODE><B>in</B><CODE> </CODE><CODE> </CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><B>let</B><CODE> </CODE>usage_msg<CODE> </CODE><CODE>=</CODE><CODE> </CODE><CODE>"usage : minesweep [-col n] [-lin n] [-min n]"</CODE><CODE> </CODE><B>in</B><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Arg.parse<CODE> </CODE>speclist<CODE> </CODE><TT>(</TT><B>fun</B><CODE> </CODE>s<CODE> </CODE>-&gt;<CODE> </CODE>()<TT>)</TT><CODE> </CODE>usage_msg;<CODE> </CODE><CODE>!</CODE>cf<CODE> </CODE>;;<BR><CODE>val read_args : unit -&gt; config = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
This function calculates a configuration that will be passed as arguments
to <TT>open_wcf</TT>, the function that opens the main window 
when the game is started. Each option is, as its name indicates, optional.
If it does not appear on the command line, the corresponding parameter
keeps its default value. The order of the options is unimportant.<BR>
<BR>

<H4> Module <TT>Filename</TT></H4>
<A NAME="@fonctions306"></A>
The <TT>Filename</TT> module has operating system independant functions to 
manipulate the names of files. In practice, the
file and directory naming conventions differ greatly
between Windows, Unix and MacOS. <BR>
<BR>

<H4> Module <TT>Printexc</TT></H4>
<A NAME="@concepts165"></A>
<A NAME="@fonctions307"></A>
This very short module (three functions described in figure <A HREF="book-ora076.html#fig-exc">8.9</A>)
provides a general exception handler. This is particularly useful 
for programs executed in command mode<A NAME="text19" HREF="book-ora081.html#note19"><SUP><FONT SIZE=2>3</FONT></SUP></A>
to be sure not to allow an exception to escape that would stop the program.
<A NAME="@fonctions308"></A>
<A NAME="@fonctions309"></A>
<A NAME="@fonctions310"></A>
<BLOCKQUOTE><DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV>
<DIV ALIGN=center>
<TABLE BORDER=1 CELLSPACING=0 CELLPADDING=1>
<TR><TD  ALIGN=left NOWRAP><TT>catch</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; 'b) -&gt; 'a -&gt; 'b</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>general exception handler</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>print</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>('a -&gt; 'b) -&gt; 'a -&gt; 'b</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>print and re-raise the exception</TD>
</TR>
<TR><TD  ALIGN=left NOWRAP><TT>to_string</TT></TD>
<TD  ALIGN=center NOWRAP>:</TD>
<TD  ALIGN=left NOWRAP><I>exn -&gt; string</I></TD>
</TR>
<TR><TD  ALIGN=left NOWRAP>&nbsp;</TD>
<TD  ALIGN=center NOWRAP>&nbsp;</TD>
<TD  ALIGN=left NOWRAP>convert an exception to a string</TD>
</TR></TABLE>
</DIV>
<BR>
<DIV ALIGN=center>Figure 8.9: Handling exceptions.</DIV><BR>

<A NAME="fig-exc"></A>
<DIV ALIGN=center><HR WIDTH="80%" SIZE=2></DIV></BLOCKQUOTE>The <TT>catch</TT> function applies its first argument to its
second. This launches the main function of the program. If an
exception arrives at the level of <TT>catch</TT>, that is to say that
if it is not handled inside the program, then <TT>catch</TT> will print
its name and exit the program. The <TT>print</TT> function has the same
behavior as <TT>catch</TT> but re-raises the exception after printing it.
Finally the <TT>to_string</TT> function converts an exception
into a character string. It is used by the two preceding functions.
If we look again at the <TT>main</TT> function for displaying
bitmaps, we might thus write an encapsulating function
<TT>go</TT> in the following manner:


<PRE><BR># <B>let</B><CODE> </CODE>go<CODE> </CODE>()<CODE> </CODE><CODE>=</CODE><CODE> </CODE><BR><CODE> </CODE><CODE> </CODE><CODE> </CODE>Printexc.catch<CODE> </CODE>main<CODE> </CODE>();;<BR><CODE>val go : unit -&gt; unit = &lt;fun&gt;</CODE><BR>

</PRE>
<BR>
<BR>
This permits the normal termination of the program by printing the
value of the uncaptured exception.<BR>
<BR>
<HR>
<A HREF="book-ora075.html"><IMG SRC ="previous_motif.gif" ALT="Previous"></A>
<A HREF="index.html"><IMG SRC ="contents_motif.gif" ALT="Contents"></A>
<A HREF="book-ora077.html"><IMG SRC ="next_motif.gif" ALT="Next"></A>
</BODY>
</HTML>
